package com.saianfu.flowable.demo.common.impl

import com.saianfu.flowable.demo.common.ActInstance
import org.flowable.engine.IdentityService
import org.flowable.engine.RuntimeService
import org.flowable.engine.TaskService
import org.flowable.engine.runtime.ProcessInstance
import org.flowable.task.api.Task
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.util.*

/**
 * 流程实例
 *
 */
@Component
class InstanceHandler : ActInstance {
    @Autowired
    lateinit var runtimeService: RuntimeService

    @Autowired
    lateinit var taskService: TaskService

    @Autowired
    lateinit var identityService: IdentityService

    @Autowired
    lateinit var histTaskQueryHandler: HistTaskQueryHandler

    @Autowired
    private val taskHandler: TaskHandler? = null
    override fun startProcessInstanceByKey(processDefinitionKey: String): ProcessInstance {
        val pi: ProcessInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey)
        logger.info("流程实例ID:{}---流程定义ID:{}", pi.id, pi.processDefinitionId)
        return pi
    }

    @Throws(Exception::class)
    override fun startInstanceAndExecuteFirstTask(processDefinitionKey: String, userId: String, variables: Map<String, Any?>): Map<String, Any?> {
        val pi: ProcessInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables)
        val instanceId = pi.processInstanceId
        logger.info("流程实例ID:{}---流程定义ID:{}", instanceId, pi.processDefinitionId)
        val finishedTask = histTaskQueryHandler.activeTask(instanceId)
        val id = finishedTask.id
        taskHandler!!.setAssignee(id, userId)
        taskHandler.setOwner(id, userId)
        //TODO 待完善：map返回的任务信息中，owner和assignee都为空，不利于业务关联表保存处理人
        taskService.complete(id, variables)
        val activeTask = histTaskQueryHandler.activeTask(instanceId)
        val map: MutableMap<String, Any?> = HashMap(16)
        logger.info("旧任务ID{}--新任务ID:{}", id, activeTask.id)
        map["finish"] = finishedTask
        map["active"] = activeTask
        return map
    }

    override fun startProcessInstanceById(processDefinitionId: String, variables: Map<String, Any?>?): ProcessInstance {
        val pi: ProcessInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables)
        logger.info("流程实例ID:{}---流程定义ID:{}", pi.id, pi.processDefinitionId)
        return pi
    }

    override fun startProcessInstanceByKey(processDefinitionKey: String, variables: Map<String, Any?>?): ProcessInstance {
        val pi: ProcessInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables)
        logger.info("流程实例ID:{}---流程定义ID:{}", pi.id, pi.processDefinitionId)
        return pi
    }

    @Throws(RuntimeException::class, Exception::class)
    override fun startProcessInstanceByKey(processDefinitionKey: String, businessKey: String?,
                                           variables: Map<String, Any?>?): ProcessInstance {
        val pi: ProcessInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables)
        logger.info("流程实例ID:{}---流程定义ID:{}", pi.id, pi.processDefinitionId)
        return pi
    }

    @Throws(RuntimeException::class, Exception::class)
    override fun suspendProcessInstanceById(processInstanceId: String) {
        runtimeService.suspendProcessInstanceById(processInstanceId)
        logger.info("成功中断流程实例ID:{}", processInstanceId)
    }

    @Throws(RuntimeException::class, Exception::class)
    override fun deleteProcessInstance(processInstanceId: String, deleteReason: String?) {
        runtimeService.deleteProcessInstance(processInstanceId, deleteReason)
        logger.info("成功删除流程实例ID:{}", processInstanceId)
    }

    override fun setAuthenticatedUserId(authenticatedUserId: String) {
        identityService.setAuthenticatedUserId(authenticatedUserId)
    }

    override fun startInstanceAndExecuteFirstTask(processDefinitionKey: String, variables: Map<String, Any?>?, actorIds: Map<String, Any?>?): ProcessInstance {
        val pi: ProcessInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables)
        logger.info("启动流程实例成功，流程实例ID:{}---流程定义ID:{}", pi.id, pi.processDefinitionId)
        val task: Task = taskService.createTaskQuery().processInstanceId(pi.processInstanceId).active().singleResult()
        taskService.complete(task.id, actorIds)
        logger.info("第一个流程任务已执行成功taskId:{}", task.id)
        return pi
    }

    override fun activateProcessInstanceById(processInstanceId: String) {
        runtimeService.activateProcessInstanceById(processInstanceId)
        logger.info("成功激活流程实例ID:{}", processInstanceId)
    }

    companion object {
        protected var logger = LoggerFactory.getLogger(InstanceHandler::class.java)
    }
}